// my_queue.h
// Created by yan on 2020/6/15.
// 队列模块。该文件主要包含一些队列结构。

#ifndef C_PROJECT_MY_QUEUE_H
#define C_PROJECT_MY_QUEUE_H


#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <stdint.h>
#include <windows.h>
#include "utils.h"


// 用来存放文件路径的结构体。
typedef struct FILENAME {
    char content[FILENAME_MAX];         // 内容，文件路径。
    struct FILENAME *next;              // 下一个结构体的地址。
} FILENAME_NODE, *pFILENAME_NODE;

// 用来存放文件路径的队列（链接构）。
typedef struct Queue_FILENAME {
    pFILENAME_NODE front;               // 队首。
    pFILENAME_NODE rear;                // 队尾。
} Queue_FILENAME, *pQueue_FILENAME;

// 队列初始化。
void Queue_FILENAME_init(pQueue_FILENAME queue) {
    queue->front = NULL;
    queue->rear = queue->front;
}

// 销毁队列，释放内存。
void Queue_FILENAME_destroy(pQueue_FILENAME queue) {
    while (queue->front != NULL) {
        pFILENAME_NODE next = queue->front->next;
        free(queue->front);
        queue->front = next;
    }
}

// 队列是否为空。
bool Queue_FILENAME_empty(pQueue_FILENAME queue) {
    return queue->front == NULL;
}

// 插入新元素到队尾。
void Queue_FILENAME_push(pQueue_FILENAME queue, const char val[]) {
    if (Queue_FILENAME_empty(queue)) {
        queue->rear = (pFILENAME_NODE) malloc(sizeof(FILENAME_NODE));
        queue->front = queue->rear;
    } else {
        queue->rear->next = (pFILENAME_NODE) malloc(sizeof(FILENAME_NODE));
        queue->rear = queue->rear->next;
    }
    strncpy(queue->rear->content, val, FILENAME_MAX);
    queue->rear->next = NULL;
}

// 从队首弹出元素。
void Queue_FILENAME_pop(pQueue_FILENAME queue, char val[]) {
    if (Queue_FILENAME_empty(queue)) return;
    strcpy(val, queue->front->content);
    pFILENAME_NODE next = queue->front->next;
    free(queue->front);
    queue->front = next;
}

// 获取队列长度。
int Queue_FILENAME_getLength(pQueue_FILENAME queue) {
    int length = 0;
    pFILENAME_NODE tmpNode = queue->front;
    while (tmpNode != NULL) {
        length++;
        tmpNode = tmpNode->next;
    }
    return length;
}

/*------------------- 消息队列 ------------------*/

// 消息体结构
typedef struct MSG_MY {
    UINT message;               // 消息内容。
    UINT param;                 // 消息附加参数。
} MSG_MY, pMSG_MY;

// 消息节点 。
typedef struct MSG_MY_NODE {
    UINT message;               // 消息内容。
    UINT param;                 // 消息附加参数。
    struct MSG_MY_NODE *next;   // 下一个结构体的地址。
} MSG_MY_NODE, *pMSG_MY_NODE;

// 消息队列（链接构）。
typedef struct Queue_MSG_MY {
    pMSG_MY_NODE front;         // 队首。
    pMSG_MY_NODE rear;          // 队尾。
} Queue_MSG_MY, *pQueue_MSG_MY;

// 队列初始化。
void Queue_MSG_MY_init(pQueue_MSG_MY queue) {
    queue->front = NULL;
    queue->rear = queue->front;
}

// 销毁队列，释放内存。
void Queue_MSG_MY_destroy(pQueue_MSG_MY queue) {
    while (queue->front != NULL) {
        pMSG_MY_NODE next = queue->front->next;
        free(queue->front);
        queue->front = next;
    }
}

// 队列是否为空。
bool Queue_MSG_MY_empty(pQueue_MSG_MY queue) {
    return queue->front == NULL;
}

// 插入新元素到队尾。
void Queue_MSG_MY_push(pQueue_MSG_MY queue, const MSG_MY *val) {
    if (Queue_MSG_MY_empty(queue)) {
        queue->rear = (pMSG_MY_NODE) malloc(sizeof(MSG_MY_NODE));
        queue->front = queue->rear;
    } else {
        queue->rear->next = (pMSG_MY_NODE) malloc(sizeof(MSG_MY_NODE));
        queue->rear = queue->rear->next;
    }
    queue->rear->message = val->message;
    queue->rear->param = val->param;
    queue->rear->next = NULL;
}

// 从队首弹出元素。
void Queue_MSG_MY_pop(pQueue_MSG_MY queue, MSG_MY *val) {
    if (Queue_MSG_MY_empty(queue)) return;
    val->message = queue->front->message;
    val->param = queue->front->param;
    pMSG_MY_NODE next = queue->front->next;
    free(queue->front);
    queue->front = next;
}

// 获取队列长度。
int Queue_MSG_MY_getLength(pQueue_MSG_MY queue) {
    int length = 0;
    pMSG_MY_NODE tmpNode = queue->front;
    while (tmpNode != NULL) {
        length++;
        tmpNode = tmpNode->next;
    }
    return length;
}

/*---------------- 计算可视化数据所需使用的队列 ----------------*/
// 双向队列。
// 用来存放 uint32_t 数据的结构体。
typedef struct UINT32_NODE {
    UINT32 data;                    // 数据。
    struct UINT32_NODE *next;       // 下一个结构体的地址。
    struct UINT32_NODE *previous;   // 上一个结构体的地址。
} UINT32_NODE, *pUINT32_NODE;

// 用来存放 uint32_t 数据的队列（链接构）。
typedef struct Queue_UINT32 {
    pUINT32_NODE front;             // 队首。
    pUINT32_NODE rear;              // 队尾。
} Queue_UINT32, *pQueue_UINT32;

// 队列初始化。
void Queue_UINT32_init(pQueue_UINT32 queue) {
    queue->front = NULL;
    queue->rear = queue->front;
}

// 销毁队列，释放内存。
void Queue_UINT32_destroy(pQueue_UINT32 queue) {
    while (queue->front != NULL) {
        pUINT32_NODE next = queue->front->next;
        free(queue->front);
        queue->front = next;
    }
}

// 队列是否为空。
bool Queue_UINT32_empty(pQueue_UINT32 queue) {
    return queue->front == NULL;
}

// 插入新元素到队尾。
void Queue_UINT32_push(pQueue_UINT32 queue, uint32_t val) {
    if (Queue_UINT32_empty(queue)) {
        queue->rear = (pUINT32_NODE) malloc(sizeof(UINT32_NODE));
        queue->front = queue->rear;
        queue->front->previous = NULL;
    } else {
        queue->rear->next = (pUINT32_NODE) malloc(sizeof(UINT32_NODE));
        queue->rear->next->previous = queue->rear;
        queue->rear = queue->rear->next;
    }
    queue->rear->data = val;
    queue->rear->next = NULL;
}

// 从队首弹出元素。
void Queue_UINT32_popFront(pQueue_UINT32 queue, uint32_t *val) {
    if (Queue_UINT32_empty(queue)) return;
    if (val != NULL) {
        *val = queue->front->data;
    }
    pUINT32_NODE next = queue->front->next;
    free(queue->front);
    queue->front = next;
    if (queue->front != NULL) {
        queue->front->previous = NULL;
    } else {
        queue->rear = NULL;
    }
}

// 获取队列长度。
int Queue_UINT32_getLength(pQueue_UINT32 queue) {
    int length = 0;
    pUINT32_NODE tmpNode = queue->front;
    while (tmpNode != NULL) {
        length++;
        tmpNode = tmpNode->next;
    }
    return length;
}

// 从队尾弹出元素。
void Queue_UINT32_popBack(pQueue_UINT32 queue, uint32_t *val) {
    if (Queue_UINT32_empty(queue)) return;
    if (val != NULL) {
        *val = queue->rear->data;
    }
    pUINT32_NODE previous = queue->rear->previous;
    free(queue->rear);
    queue->rear = previous;
    if (queue->rear != NULL) {
        queue->rear->next = NULL;
    } else {
        queue->front = NULL;
    }
}

// 获取队首数据。
uint32_t Queue_UINT32_front(pQueue_UINT32 queue) {
    return queue->front->data;
}
// 获取队尾数据。
uint32_t Queue_UINT32_back(pQueue_UINT32 queue) {
    return queue->rear->data;
}

#endif //C_PROJECT_MY_QUEUE_H
